package com.ruoyi.project.bajiaostar.tGoodOrder.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.bajiaostar.tGood.domain.TGood;
import com.ruoyi.project.bajiaostar.tGood.service.ITGoodService;
import com.ruoyi.project.bajiaostar.tGoodDetail.domain.TGoodDetail;
import com.ruoyi.project.bajiaostar.tGoodDetail.service.ITGoodDetailService;
import com.ruoyi.project.bajiaostar.tGoodOrder.domain.*;
import com.ruoyi.project.bajiaostar.tOrderStayRecord.domain.TOrderStayRecord;
import com.ruoyi.project.bajiaostar.tOrderStayRecord.service.ITOrderStayRecordService;
import com.ruoyi.project.bajiaostar.tUserAmount.domain.TUserAmount;
import com.ruoyi.project.bajiaostar.tUserAmount.service.ITUserAmountService;
import com.ruoyi.project.bajiaostar.tUserAmountDetail.domain.TUserAmountDetail;
import com.ruoyi.project.bajiaostar.tUserAmountDetail.service.ITUserAmountDetailService;
import com.ruoyi.project.bajiaostar.user.dto.AddGoodOrderDto;
import com.ruoyi.project.mail.service.IMailService;
import com.ruoyi.project.system.user.service.IUserService;
import com.ruoyi.project.user.domain.TUser;
import com.ruoyi.project.user.service.ITUserService;
import com.ruoyi.project.utils.ExcelUtil;
import com.ruoyi.project.utils.MailUtil;
import com.ruoyi.project.utils.RedisUtils;
import com.ruoyi.project.utils.SnowFlakeUtil;
import com.sun.xml.bind.v2.TODO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import com.ruoyi.project.bajiaostar.tGoodOrder.mapper.TGoodOrderMapper;
import com.ruoyi.common.utils.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import com.ruoyi.project.bajiaostar.tGoodOrder.service.ITGoodOrderService;

import javax.mail.MessagingException;

/**
 * 商品详情信息Service业务层处理
 *
 * @author wangwu
 * @date 2024-05-21
 */
@Service
@Slf4j
public class TGoodOrderServiceImpl implements ITGoodOrderService {
    @Autowired
    private TGoodOrderMapper tGoodOrderMapper;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    ITGoodDetailService goodDetailService;
    @Autowired
    ITUserService userService;
    @Autowired
    ITGoodService goodService;
    @Autowired
    ITUserAmountService userAmountService;
    @Autowired
    ITUserAmountDetailService userAmountDetailService;
    @Autowired
    IMailService mailService;
    @Value("${ruoyi.profile}")
    private String filePath;
    @Value("${spring.profiles.active}")
    private String active;
    @Autowired
    com.ruoyi.project.system.user.service.IUserService sysUserService;
    @Autowired
    ITOrderStayRecordService orderStayRecordService;


    /**
     * 查询商品详情信息
     *
     * @param id 商品详情信息ID
     * @return 商品详情信息
     */
    @Override
    public TGoodOrder selectTGoodOrderById(Long id) {
        return tGoodOrderMapper.selectTGoodOrderById(id);
    }

    /**
     * 查询商品详情信息列表
     *
     * @param tGoodOrder 商品详情信息
     * @return 商品详情信息
     */
    @Override
    public List<TGoodOrder> selectTGoodOrderList(TGoodOrder tGoodOrder) {
        return tGoodOrderMapper.selectTGoodOrderList(tGoodOrder);
    }

    /**
     * 查询商品详情信息列表(客户端)
     *
     * @param tGoodOrder 商品详情信息
     * @return 商品详情信息集合
     */
    @Override
    public List<TGoodOrder> selectTGoodOrderUserList(TGoodOrder tGoodOrder) {
        return tGoodOrderMapper.selectTGoodOrderUserList(tGoodOrder);
    }

    /**
     * 新增商品详情信息
     *
     * @param tGoodOrder 商品详情信息
     * @return 结果
     */
    @Override
    public int insertTGoodOrder(TGoodOrder tGoodOrder) {
        tGoodOrder.setCreateTime(DateUtils.getNowDate());
        return tGoodOrderMapper.insertTGoodOrder(tGoodOrder);
    }

    /**
     * 修改商品详情信息
     *
     * @param tGoodOrder 商品详情信息
     * @return 结果
     */
    @Override
    public int updateTGoodOrder(TGoodOrder tGoodOrder) {
        tGoodOrder.setUpdateTime(DateUtils.getNowDate());
        return tGoodOrderMapper.updateTGoodOrder(tGoodOrder);
    }

    /**
     * 删除商品详情信息对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteTGoodOrderByIds(String ids) {
        return tGoodOrderMapper.deleteTGoodOrderByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除商品详情信息信息
     *
     * @param id 商品详情信息ID
     * @return 结果
     */
    @Override
    public int deleteTGoodOrderById(Long id) {
        return tGoodOrderMapper.deleteTGoodOrderById(id);
    }

    /**
     * 下单
     *
     * @param req
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addGoodOrder(AddGoodOrderDto req) {

        boolean b = redisUtils.setLock("lock:goodorder:" + req.getDetailId(), 3);
        if (!b) {
            return AjaxResult.error("哦豁，系统太繁忙了,请稍后再试");
        }
        //获取下单详情
        TGoodDetail detail = goodDetailService.selectTGoodDetailById(req.getDetailId());
        if (ObjectUtils.isEmpty(detail)) {
            return AjaxResult.error("详情id有误,请检查");
        }
        //查询商品是否存在
        TGood good = goodService.selectTGoodById(req.getGoodId());
        if (ObjectUtils.isEmpty(good)) {
            return AjaxResult.error("商品不存在或已下架");
        }
        if (good.getGoodStatus().equals(1)) {
            return AjaxResult.error("商品已下架");
        }
        if (good.getGoodStatus().equals(2)) {
            return AjaxResult.error("商品状态不正确,请联系管理员");
        }
        //获取用户信息
        TUser user = userService.selectTUserById(req.getUserId());
        if (ObjectUtils.isEmpty(user)) {
            return AjaxResult.error("用户不存在,请检查");
        }
        if (user.getUserStatus().equals(1)) {
            return AjaxResult.error("用户已被禁用,请联系客服人员");
        }
        //判断库存是否足够
        if (detail.getInventory() < req.getQuantity()) {
            return AjaxResult.error("库存不足");
        }
        //添加下单记录
        TGoodOrder order = new TGoodOrder();
        order.setUserId(req.getUserId());
        order.setGoodName(good.getGoodName());
        order.setGoodDate(detail.getGoodDate());
        order.setWeek(detail.getWeek());
        order.setTicketPrice(new BigDecimal(detail.getTicketPrice()+"").intValue());
        order.setParagraph(detail.getParagraph());
        order.setGoodRow(detail.getGoodRow());
        order.setSeatNumber(detail.getSeatNumber());
        order.setInventory(detail.getInventory());
        order.setPrice(new BigDecimal(detail.getPrice()+"").intValue());
        order.setDefaultSettlementPrice(new BigDecimal(detail.getDefaultSettlementPrice()+"").intValue());
        order.setMemberSettlementPrice(new BigDecimal(detail.getMemberSettlementPrice()+"").intValue());
        order.setOrderAddress(req.getOrderAddress());
        order.setOverdueDete(DateUtils.addMinuteTime(new Date(), 30));
        order.setOrderStatus(0);
        order.setBuyNum(req.getQuantity());
        order.setDisplayInventory(detail.getDisplayInventory());
        order.setTwoMemberSettlementPrice(new BigDecimal(detail.getTwoMemberSettlementPrice()+"").intValue());
        order.setGoodRemark(detail.getRemark());
        order.setTwoMemberSettlementCountPrice(new BigDecimal((detail.getTwoMemberSettlementPrice() * req.getQuantity())+"").intValue());
        order.setDefaultSettlementCountPrice(new BigDecimal((detail.getDefaultSettlementPrice() * req.getQuantity())+"").intValue());
        order.setMemberSettlementCountPrice(new BigDecimal((detail.getMemberSettlementPrice() * req.getQuantity())+"").intValue());
        order.setRecipientsName(req.getRecipientsName());
        order.setRecipientsPhone(req.getRecipientsPhone());
        order.setGoodId(good.getId());
        order.setGoodDetailId(detail.getId());
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setUserIdentity(user.getUserIdentity());
        order.setOrderNo(""+SnowFlakeUtil.getDefaultSnowFlakeId());
        order.setUserStayPayPrice(0);
        order.setChangeFlag(0);
        order.setChangeTime(new Date());
        int i = tGoodOrderMapper.insertTGoodOrder(order);
        if (i < 1) {
            throw new RuntimeException("下单异常");
        }
        detail.setInventory(detail.getInventory() - req.getQuantity());
        int i1 = goodDetailService.updateTGoodDetail(detail);
        if (i1 < 1) {
            throw new RuntimeException("下单异常");
        }
        try {
            redisUtils.unLock("lock:goodorder:" + req.getDetailId());
        } catch (Exception e) {
            log.error("释放锁失败：{}", e);
        }
        return AjaxResult.success("下单成功");
    }

    /**
     * 修改地址
     *
     * @param orderId
     * @param address
     * @return
     */
    @Override
    public AjaxResult updateGoodOrderForAddress(Long orderId, String address, String name, String phone, String someRemark, String userRemark) {
        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            return AjaxResult.error("订单不存在");
        }
        goodOrder.setOrderAddress(address);
        goodOrder.setRecipientsName(name);
        goodOrder.setRecipientsPhone(phone);
        goodOrder.setSomeRemark(someRemark);
        goodOrder.setUserRemark(userRemark);
        goodOrder.setChangeFlag(0);
        goodOrder.setChangeTime(new Date());
        int i = tGoodOrderMapper.updateTGoodOrder(goodOrder);
        if (i < 1) {
            return AjaxResult.error("地址修改失败");
        }
        return AjaxResult.success();
    }


    /**
     * 修改订单待结算金额
     *
     * @param orderId
     * @param userStayPayPrice
     * @return
     */
    @Override
    public AjaxResult updateUserStayPayPrice(Long orderId, BigDecimal userStayPayPrice) {
        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            return AjaxResult.error("订单不存在");
        }
        Integer userStayPayPriceAgo = goodOrder.getPrice() * goodOrder.getBuyNum();
        if(goodOrder.getUserStayPayPrice() < 1){
            if (goodOrder.getUserIdentity().equals(0)) {
                userStayPayPriceAgo = userStayPayPriceAgo - goodOrder.getDefaultSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(1)) {
                userStayPayPriceAgo = userStayPayPriceAgo - goodOrder.getMemberSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(2)) {
                userStayPayPriceAgo = userStayPayPriceAgo - goodOrder.getTwoMemberSettlementCountPrice();
            }

        }else{
            userStayPayPriceAgo =  goodOrder.getUserStayPayPrice();
        }
        goodOrder.setUserStayPayPrice(userStayPayPrice.intValue());
        int i = tGoodOrderMapper.updateTGoodOrder(goodOrder);
        if (i < 1) {
            return AjaxResult.error("变待结算更金额修改失败");
        }

        //添加变更金额记录
        TOrderStayRecord record=new TOrderStayRecord();
        record.setOrderId(orderId);
        record.setUpdateStayPriceAgo(userStayPayPriceAgo);
        record.setUpdateStayPriceAfter(userStayPayPrice.intValue());
        record.setCreateTime(new Date());
        orderStayRecordService.insertTOrderStayRecord(record);


        /********************************修改结算金额开始***************************************************/
        executeOrder(orderId);
        /********************************修改结算金额结束***************************************************/
        return AjaxResult.success();
    }

    /**
     * 修改订单状态
     *
     * @param orderId
     * @param orderStatus
     * @return
     */
    @Override
    @Transactional
    public AjaxResult updateGoodOrderForStatus(Long orderId, Integer orderStatus,Integer cancelType) {
        boolean b = redisUtils.setLock("lock:goodorder:" + orderId, 10);
        if (!b) {
            return AjaxResult.error("哦豁，系统太繁忙了,请稍后再试");
        }
        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            return AjaxResult.error("订单不存在");
        }
        if (goodOrder.getOrderStatus().equals(3)) {
            return AjaxResult.error("取消状态订单不能修改状态");
        }
        goodOrder.setOrderStatus(orderStatus);
        if(orderStatus.equals(3)){
            if(ObjectUtils.isEmpty(cancelType)){
                return AjaxResult.error("取消订单,类型不能为空");
            }
            goodOrder.setCancelType(cancelType);
        }
        int i = tGoodOrderMapper.updateTGoodOrder(goodOrder);
        if (i < 1) {
            return AjaxResult.error("失败");
        }
        //完成已发货
        if (orderStatus.equals(1)) {
            //查询用户信息
            TUser user = userService.selectTUserById(goodOrder.getUserId());
            if (ObjectUtils.isEmpty(user)) {
                throw new RuntimeException("用户不存在");
            }
            //查询账户信息
            TUserAmount amount = userAmountService.selectTUserAmountByUserId(user.getId());
            if (ObjectUtils.isEmpty(amount)) {
                throw new RuntimeException("账户不存在");
            }
            Integer stayPay = goodOrder.getPrice() * goodOrder.getBuyNum();
            Integer incomeAmount = 0;
            if(goodOrder.getUserStayPayPrice() < 1){
                if (goodOrder.getUserIdentity().equals(0)) {
                    incomeAmount = goodOrder.getDefaultSettlementCountPrice();
                    stayPay = stayPay - goodOrder.getDefaultSettlementCountPrice();
                } else if (goodOrder.getUserIdentity().equals(1)) {
                    incomeAmount = goodOrder.getMemberSettlementCountPrice();
                    stayPay = stayPay - goodOrder.getMemberSettlementCountPrice();
                } else if (goodOrder.getUserIdentity().equals(2)) {
                    incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
                    stayPay = stayPay - goodOrder.getTwoMemberSettlementCountPrice();
                }
            }else{
                stayPay = goodOrder.getUserStayPayPrice();
                if (goodOrder.getUserIdentity().equals(0)) {
                    incomeAmount = goodOrder.getDefaultSettlementCountPrice();
                } else if (goodOrder.getUserIdentity().equals(1)) {
                    incomeAmount = goodOrder.getMemberSettlementCountPrice();
                } else if (goodOrder.getUserIdentity().equals(2)) {
                    incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
                }
            }
            amount.setIncomeAmount(amount.getIncomeAmount() + incomeAmount);
            amount.setStayPayAmount(amount.getStayPayAmount() - stayPay);
            int i1 = userAmountService.updateTUserAmount(amount);
            if (i1 < 1) {
                throw new RuntimeException("更新账户失败");
            }
            //查询是否存在资金记录 存在跳过资金记录
            TUserAmountDetail userAmountDetail = userAmountDetailService.findTUserAmountDetail(orderId, 0, goodOrder.getOrderNo(), user.getId());
            if(ObjectUtils.isEmpty(userAmountDetail)){
                //插入资金详细
                TUserAmountDetail detail = new TUserAmountDetail();
                detail.setUserId(user.getId());
                detail.setDetailName(goodOrder.getGoodName());
                detail.setDetailType(0);
                String text = "场次 " + DateUtils.parseDateToStr("MM/dd", goodOrder.getGoodDate()) + ",票面 " + new BigDecimal(goodOrder.getTicketPrice()+"").longValue() + "," + goodOrder.getParagraph() + "段 ," + goodOrder.getGoodRow() + "行 ,座位号 " + goodOrder.getSeatNumber();
                detail.setDetailRemark(text);
                detail.setPrice(goodOrder.getPrice());
                detail.setQuantity(goodOrder.getBuyNum());
                detail.setStayPayAmount(stayPay);
                detail.setSurplusAmount(incomeAmount);
                detail.setOrderId(orderId);
                detail.setOrderNo(goodOrder.getOrderNo());
                detail.setGoodId(goodOrder.getGoodId());
                userAmountDetailService.insertTUserAmountDetail(detail);
            }
        } else if (orderStatus.equals(3)) {
            //查询库存
            TGoodDetail detail = goodDetailService.selectTGoodDetailById(goodOrder.getGoodDetailId());
            if (ObjectUtils.isEmpty(detail)) {
                System.out.println("查询库存失败，信息为空：orderId：" + goodOrder.getGoodDetailId());
                throw new RuntimeException("取消订单失败");
            }
            detail.setInventory(detail.getInventory() + goodOrder.getBuyNum());
            goodDetailService.updateTGoodDetail(detail);

            /********************************修改结算金额开始***************************************************/
            executeOrderCancel(orderId);
            /********************************修改结算金额结束***************************************************/
        }
        return AjaxResult.success();
    }


    @Override
    @Transactional
    public AjaxResult updateGoodOrderStatus(Long orderId) {
        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            return AjaxResult.error("订单不存在");
        }
        goodOrder.setOrderStatus(1);
        int i = tGoodOrderMapper.updateTGoodOrder(goodOrder);
        if (i < 1) {
            return AjaxResult.error("修改失败");
        }
        //查询账户信息
        TUserAmount amount = userAmountService.selectTUserAmountByUserId(goodOrder.getUserId());
        if (ObjectUtils.isEmpty(amount)) {
            throw new RuntimeException("账户不存在");
        }
        Integer stayPay = goodOrder.getPrice() * goodOrder.getBuyNum();
        Integer incomeAmount = 0;
        if(goodOrder.getUserStayPayPrice() < 1){
            if (goodOrder.getUserIdentity().equals(0)) {
                incomeAmount = goodOrder.getDefaultSettlementCountPrice();
                stayPay = stayPay - goodOrder.getDefaultSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(1)) {
                incomeAmount = goodOrder.getMemberSettlementCountPrice();
                stayPay = stayPay - goodOrder.getMemberSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(2)) {
                incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
                stayPay = stayPay - goodOrder.getTwoMemberSettlementCountPrice();
            }
        }else{
            stayPay = goodOrder.getUserStayPayPrice();
            if (goodOrder.getUserIdentity().equals(0)) {
                incomeAmount = goodOrder.getDefaultSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(1)) {
                incomeAmount = goodOrder.getMemberSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(2)) {
                incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
            }
        }
        amount.setIncomeAmount(amount.getIncomeAmount() - incomeAmount);
        amount.setStayPayAmount(amount.getStayPayAmount() + stayPay);
     /*   int i1 = userAmountService.updateTUserAmount(amount);
        if (i1 < 1) {
            throw new RuntimeException("更新账户失败");
        }*/

        return AjaxResult.success();

    }
    /**
     * 定制任务
     *
     * @return
     */
    @Override
    public AjaxResult updateOrderOverdueDeteTask() {
        log.info("过期定时任务执行开始");
        List<TGoodOrder> orders = tGoodOrderMapper.findOrderOverdueDete();
        if (ObjectUtils.isEmpty(orders)) {
            log.info("过期定时任务执行中，暂无数据执行");
            return AjaxResult.success();
        }
        for (TGoodOrder order : orders) {
            //查询库存
            TGoodDetail detail = goodDetailService.selectTGoodDetailById(order.getGoodDetailId());
            if (ObjectUtils.isEmpty(detail)) {
                System.out.println("查询库存失败，信息为空：orderId：" + order.getGoodDetailId());
                continue;
            }
            System.out.printf(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date())+"订单支付超市取消：商品详情id："+order.getGoodDetailId());
            detail.setInventory(detail.getInventory() + order.getBuyNum());
            goodDetailService.updateTGoodDetail(detail);
            //更新订单状态
            tGoodOrderMapper.updateOrderOverdueDete(order.getId());
            System.out.println("查询库存成功：GoodDetailId：" + order.getGoodDetailId());
        }
        log.info("过期定时任务执行结束");
        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date())+"过期定时任务执行结束");
        return AjaxResult.success();
    }

    /**
     * 发送当日邮件
     *
     * @return
     */
    @Override
    public AjaxResult execueOrderMailDeteTask() throws IOException {
        log.info("发送当日邮件定时任务执行开始");
        //查出今天所有订单
        List<TGoodOrder> orderList = tGoodOrderMapper.findGoodOrderByDate();
        if (ObjectUtils.isEmpty(orderList)) {
            log.info("暂无可自行数据");
            return AjaxResult.success();
        }
        List<AdminMailGoodVo> adminList = new ArrayList<>();
        List<UserMailGoodVo> userList = new ArrayList<>();
        //转换成发送邮件信息
        for (TGoodOrder order : orderList) {
            //查询用户信息
            TUser user = userService.selectTUserById(order.getUserId());
            if (ObjectUtils.isEmpty(user)) {
                continue;
            }
            AdminMailGoodVo adminVo = new AdminMailGoodVo();
            UserMailGoodVo userVo = new UserMailGoodVo();
            BeanUtil.copyProperties(order, adminVo);
            BeanUtil.copyProperties(order, userVo);
            adminVo.setOrderTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,order.getCreateTime()));
            userVo.setOrderTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,order.getCreateTime()));

            Integer stayPay = order.getPrice() * order.getBuyNum();
            Integer incomeAmount = 0;
            String userIdentityName = "";
            if (order.getUserIdentity().equals(0)) {
                incomeAmount = order.getDefaultSettlementCountPrice();
                stayPay = stayPay - order.getDefaultSettlementCountPrice();
                userIdentityName = "默认";
            } else if (order.getUserIdentity().equals(1)) {
                incomeAmount = order.getMemberSettlementCountPrice();
                stayPay = stayPay - order.getMemberSettlementCountPrice();
                userIdentityName = "VIP";
            } else if (order.getUserIdentity().equals(2)) {
                incomeAmount = order.getTwoMemberSettlementCountPrice();
                stayPay = stayPay - order.getTwoMemberSettlementCountPrice();
                userIdentityName = "VVIP";
            }
            if(order.getUserStayPayPrice() >1){
                stayPay=order.getUserStayPayPrice();
            }
            adminVo.setOrderNo(order.getOrderNo());
            adminVo.setSettlementCountPrice(-incomeAmount);
            adminVo.setStayPayCountPrice(stayPay);
            adminVo.setGoodDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, order.getGoodDate()));
            adminVo.setOrderAddress(order.getOrderAddress());
            adminVo.setRecipientsName(order.getRecipientsName());
            adminVo.setRecipientsPhone(order.getRecipientsPhone());
            adminVo.setSomeRemark(order.getSomeRemark());
            BigDecimal price = new BigDecimal(stayPay+"").divide(new BigDecimal(order.getBuyNum()+""),0,BigDecimal.ROUND_HALF_UP);
            adminVo.setStayPayPrice(price.intValue());

            userVo.setIncomePrice(-incomeAmount);
            userVo.setStayPayCountPrice(stayPay);
            userVo.setUserId(user.getId());
            userVo.setUserMail(user.getMobile());
            userVo.setGoodDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, order.getGoodDate()));
            userVo.setUserRemark(order.getUserRemark());
            userVo.setStayPayPrice(price.intValue());

            adminVo.setUserName(user.getMobile());
            adminVo.setUserRemark(user.getUserRemark());
            adminVo.setUserIdentityName(userIdentityName);
            //计算两个时间差
            long dayPoorDay = DateUtils.getDayPoorDay(new Date(), order.getChangeTime());
            if(order.getChangeFlag().equals(1) && dayPoorDay >-1 && dayPoorDay < 2){
                adminVo.setAddressFlag("地址已更新");
            }

            if (order.getOrderStatus().equals(1)) {
                adminList.add(adminVo);
            }
            //只发送变更数据或刚下单数据
            if( dayPoorDay >-1 && dayPoorDay < 2){
                userList.add(userVo);
            }

        }
        if (!ObjectUtils.isEmpty(adminList)) {
            List<String> queryUserList = sysUserService.queryUserList();
            //发送管理员邮件
            try {
                if (!ObjectUtils.isEmpty(queryUserList)) {
                    // 生成excel文件
                    ByteArrayOutputStream out = ExcelUtil.generateExcel(adminList, AdminMailGoodVo.class);
                    String path = filePath + "/" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date()) + "每日信息.xlsx";
                    FileOutputStream fos = new FileOutputStream(new File(path));
                    out.writeTo(fos);
                    for (String str : queryUserList) {
                        if (isValidEmail(str)) {
                            if(active.equals("prod")){
                                //获取所有管理员
                                mailService.sendAttachmentMailMessage("muikinching413@gmail.com", "每日订单", "每日订单统计情在附件中，请查看", path);
                                mailService.sendAttachmentMailMessage("xshxxm@163.com", "每日订单"+str, "每日订单统计情在附件中，请查看", path);
                            }else{
                                //获取所有管理员
                                mailService.sendAttachmentMailMessage(str, "每日订单", "每日订单统计情在附件中，请查看", path);
                                mailService.sendAttachmentMailMessage("xshxxm@163.com", "每日订单"+str, "每日订单统计情在附件中，请查看", path);
                            }

                        }
                    }
                }

            } catch (Exception e) {
                log.error("发送管理员邮件失败：{}", e);
            }
        }

        Map<Long, List<UserMailGoodVo>> map = userList.stream()
                .collect(Collectors.groupingBy(UserMailGoodVo::getUserId));

        //遍历map
        for (Long mapKey : map.keySet()) {
            List<UserMailGoodVo> mapValue = map.get(mapKey);
            //发送用户提醒邮件
            try {
                if(!ObjectUtils.isEmpty(mapValue)){
                    // 生成excel文件
                    ByteArrayOutputStream out = ExcelUtil.generateExcel(mapValue, UserMailGoodVo.class);
                    String path = filePath + "/" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date())  + "每日信息.xlsx";
                    FileOutputStream fos = new FileOutputStream(new File(path));
                    out.writeTo(fos);
                    if(active.equals("prod")){
                        mailService.sendAttachmentMailMessage("apesliyunlong@gmail.com", "每日订单", "每日订单统计情在附件中，请查看,支付宝\n" +
                                "\n" +
                                "18529091248 陈\n" +
                                "mikelau864@gmail.com 刘\n" +
                                "\n" +
                                "请选定其中一个支付宝\n" +
                                "转帐必须截图并微信发给梅菲\n", path);
                    }else{
                        mailService.sendAttachmentMailMessage(mapValue.get(0).getUserMail(), "每日订单", "每日订单统计情在附件中，请查看,支付宝\n" +
                                "\n" +
                                "18529091248 陈\n" +
                                "mikelau864@gmail.com 刘\n" +
                                "\n" +
                                "请选定其中一个支付宝\n" +
                                "转帐必须截图并微信发给梅菲\n", path);
                    }
                }
                // mailService.sendAttachmentMailMessage(mapValue.get(0).getUserMail(),DateUtils.dateTimeNow() + "用户订单提醒","订单提醒在附件中，请查看",new ByteArrayResource(out.toByteArray()),DateUtils.dateTimeNow()+"用户订单提醒.xlsx");
            } catch (Exception e) {
                log.error("发送用户提醒邮件失败：{}", e);
            }
        }
        log.info("发送当日邮件定时任务执行结束");
        System.out.println("发送当日邮件定时任务执行结束");

        try {
            sendAdminFlatAmountEmail();
        }catch (Exception e){
            log.info("发送当日平账邮件定时任务执行结束");
            System.out.println("发送当日平账邮件定时任务执行结束");
        }


        return AjaxResult.success();
    }

    /**
     * 发送当日邮件(管理员)
     * @return
     * @throws IOException
     */
    @Override
    public AjaxResult execueOrderMailDeteAdminTask() throws IOException {
        log.info("发送当日邮件定时任务执行开始");
        //查出今天所有订单
        List<TGoodOrder> orderList = tGoodOrderMapper.findGoodOrderByDate();
        if (ObjectUtils.isEmpty(orderList)) {
            log.info("暂无可自行数据");
            return AjaxResult.success();
        }
        List<AdminMailGoodVo> adminList = new ArrayList<>();
        List<UserMailGoodVo> userList = new ArrayList<>();
        //转换成发送邮件信息
        for (TGoodOrder order : orderList) {
            //查询用户信息
            TUser user = userService.selectTUserById(order.getUserId());
            if (ObjectUtils.isEmpty(user)) {
                continue;
            }
            AdminMailGoodVo adminVo = new AdminMailGoodVo();
            UserMailGoodVo userVo = new UserMailGoodVo();
            BeanUtil.copyProperties(order, adminVo);
            BeanUtil.copyProperties(order, userVo);
            Integer stayPay = order.getPrice() * order.getBuyNum();
            Integer incomeAmount = 0;
            String userIdentityName = "";
            if (order.getUserIdentity().equals(0)) {
                incomeAmount = order.getDefaultSettlementCountPrice();
                stayPay = stayPay - order.getDefaultSettlementCountPrice();
                userIdentityName = "默认";
            } else if (order.getUserIdentity().equals(1)) {
                incomeAmount = order.getMemberSettlementCountPrice();
                stayPay = stayPay - order.getMemberSettlementCountPrice();
                userIdentityName = "VIP";
            } else if (order.getUserIdentity().equals(2)) {
                incomeAmount = order.getTwoMemberSettlementCountPrice();
                stayPay = stayPay - order.getTwoMemberSettlementCountPrice();
                userIdentityName = "VVIP";
            }
            if(order.getUserStayPayPrice() >1){
                stayPay=order.getUserStayPayPrice();
            }
            adminVo.setOrderNo(order.getOrderNo());
            adminVo.setSettlementCountPrice(-incomeAmount);
            adminVo.setStayPayCountPrice(stayPay);
            adminVo.setGoodDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, order.getGoodDate()));
            adminVo.setOrderAddress(order.getOrderAddress());
            adminVo.setRecipientsName(order.getRecipientsName());
            adminVo.setRecipientsPhone(order.getRecipientsPhone());
            adminVo.setSomeRemark(order.getSomeRemark());
            BigDecimal price = new BigDecimal(stayPay+"").divide(new BigDecimal(order.getBuyNum()+""),0,BigDecimal.ROUND_HALF_UP);
            adminVo.setStayPayPrice(price.intValue());

            userVo.setIncomePrice(-incomeAmount);
            userVo.setStayPayCountPrice(stayPay);
            userVo.setUserId(user.getId());
            userVo.setUserMail(user.getMobile());
            userVo.setGoodDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, order.getGoodDate()));
            userVo.setUserRemark(order.getUserRemark());
            userVo.setStayPayPrice(price.intValue());

            adminVo.setUserName(user.getMobile());
            adminVo.setUserRemark(user.getUserRemark());
            adminVo.setUserIdentityName(userIdentityName);
            if (order.getOrderStatus().equals(1)) {
                adminList.add(adminVo);
            }
            userList.add(userVo);
        }
        if (!ObjectUtils.isEmpty(adminList)) {
            List<String> queryUserList = sysUserService.queryUserList();
            //发送管理员邮件
            try {
                if (!ObjectUtils.isEmpty(queryUserList)) {
                    // 生成excel文件
                    ByteArrayOutputStream out = ExcelUtil.generateExcel(adminList, AdminMailGoodVo.class);
                    String path = filePath + "/" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date()) + "每日信息.xlsx";
                    FileOutputStream fos = new FileOutputStream(new File(path));
                    out.writeTo(fos);
                    for (String str : queryUserList) {
                        if (isValidEmail(str)) {
                            if(active.equals("prod")){
                                //获取所有管理员
                                mailService.sendAttachmentMailMessage("muikinching413@gmail.com", "每日订单", "每日订单统计情在附件中，请查看", path);
                                mailService.sendAttachmentMailMessage("xshxxm@163.com", "每日订单"+str, "每日订单统计情在附件中，请查看", path);
                            }else{
                                //获取所有管理员
                                mailService.sendAttachmentMailMessage(str, "每日订单", "每日订单统计情在附件中，请查看", path);
                                mailService.sendAttachmentMailMessage("xshxxm@163.com", "每日订单"+str, "每日订单统计情在附件中，请查看", path);
                            }
                        }
                    }
                }

            } catch (Exception e) {
                log.error("发送管理员邮件失败：{}", e);
            }
        }
        log.info("发送当日邮件定时任务执行结束");
        System.out.println("发送当日邮件定时任务执行结束");
        return AjaxResult.success();
    }

    @Override
    public int findOrderCountByStatus(Integer status) {
        return tGoodOrderMapper.findOrderCountByStatus(status);
    }

    @Override
    public AjaxResult findStayOrder(Long goodId) {
        TGoodOrder goodOrder=new TGoodOrder();
        goodOrder.setOrderStatus(4);
        goodOrder.setGoodId(goodId);
        List<TGoodOrder> list=selectTGoodOrderList(goodOrder);
        return AjaxResult.success(list);
    }


    /**
     * 根据用户id查询所有平账数据并发送给管理员
     */
    private void sendAdminFlatAmountEmail() throws IOException {
        TUserAmountDetail detail=new TUserAmountDetail();
       // detail.setUserId(userId);
        detail.setDetailType(1);
        detail.setStartTime(DateUtils.getBeginDate(DateUtils.addDayTime(new Date(),-1)));
        detail.setEndTime(DateUtils.getEndDate(new Date()));
        List<TUserAmountDetail> list = userAmountDetailService.selectTUserAmountDetailList(detail);
        if(ObjectUtils.isEmpty(list)){
            return;
        }
        List<SendUserFlatAmountForAdminVo> adminMailList=new ArrayList<>();
        for (TUserAmountDetail detail1:list) {
            TUser user = userService.selectTUserById(detail1.getUserId());
            SendUserFlatAmountForAdminVo adminVo = new SendUserFlatAmountForAdminVo();
            adminVo.setTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,detail1.getCreateTime()));
            adminVo.setFlatPayAmount(detail1.getFlatPayAmount());
            adminVo.setGiveAmount(detail1.getGiveAmount());
            adminVo.setStayPayAmount(detail1.getStayPayAmount());
            adminVo.setSurplusAmount(detail1.getSurplusAmount());
            adminVo.setRemark(detail1.getRemark());
            adminVo.setUserName(user.getMobile());
            adminMailList.add(adminVo);
        }

        //发送管理员邮件
        if(active.equals("prod")){
            // 生成excel文件
            ByteArrayOutputStream out = ExcelUtil.generateExcel(adminMailList, SendUserFlatAmountForAdminVo.class);
            String path = filePath + "/" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date())  + "平账历史.xlsx";
            FileOutputStream fos = new FileOutputStream(new File(path));
            out.writeTo(fos);
            mailService.sendAttachmentMailMessage("muikinching413@gmail.com", "平账历史", "历史平账户信息统计情在附件中" , path);
        }else{
            List<String> queryUserList = sysUserService.queryUserList();
            // 生成excel文件
            ByteArrayOutputStream out = ExcelUtil.generateExcel(adminMailList, SendUserFlatAmountForAdminVo.class);
            String path = filePath + "/" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date())  + "平账历史.xlsx";
            FileOutputStream fos = new FileOutputStream(new File(path));
            out.writeTo(fos);
            if (!ObjectUtils.isEmpty(queryUserList)) {
                for (String str : queryUserList) {
                    if (isValidEmail(str)) {
                        mailService.sendAttachmentMailMessage(str, "平账历史", "历史平账信息统计情在附件中" , path);
                    }
                }
            }
        }

    }

    /**
     * 查询所有下单商品名称
     *
     * @param userId
     * @return
     */
    @Override
    public AjaxResult findStayOrderByUserId(Long userId) {
        List<TGoodOrder> list = tGoodOrderMapper.findStayOrderByUserId(userId);
        return AjaxResult.success(list);
    }


    private static final String EMAIL_PATTERN =
            "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";

    private static final Pattern EMAIL_REGEX = Pattern.compile(EMAIL_PATTERN);

    public static boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        return EMAIL_REGEX.matcher(email).matches();
    }

    /**
     * 取消计算结算信息
     */
    private void executeOrderCancel(Long orderId){

        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            throw new RuntimeException("订单不存在");
        }
        //查询用户信息
        TUser user = userService.selectTUserById(goodOrder.getUserId());
        if (ObjectUtils.isEmpty(user)) {
            throw new RuntimeException("用户不存在");
        }
        //查询账户信息
        TUserAmount amount = userAmountService.selectTUserAmountByUserId(user.getId());
        if (ObjectUtils.isEmpty(amount)) {
            throw new RuntimeException("账户不存在");
        }
        //查询以前的结算明细
        TUserAmountDetail detail = userAmountDetailService.findTUserAmountDetailByOrderId(goodOrder.getId());
        //减去以前的明细
        if(!ObjectUtils.isEmpty(detail)){
            amount.setIncomeAmount(amount.getIncomeAmount() - detail.getSurplusAmount());
            amount.setStayPayAmount(amount.getStayPayAmount() + detail.getStayPayAmount());
            int i1 = userAmountService.updateTUserAmount(amount);
            if (i1 < 1) {
                throw new RuntimeException("更新账户失败");
            }
            userAmountDetailService.deleteTUserAmountDetailById(detail.getId());
        }
    }


    /**
     * 重新计算结算信息
     */
    private void executeOrder (Long orderId){

        //查询订单
        TGoodOrder goodOrder = tGoodOrderMapper.selectTGoodOrderById(orderId);
        if (ObjectUtils.isEmpty(goodOrder)) {
            throw new RuntimeException("订单不存在");
        }
        //查询用户信息
        TUser user = userService.selectTUserById(goodOrder.getUserId());
        if (ObjectUtils.isEmpty(user)) {
            throw new RuntimeException("用户不存在");
        }
        //查询账户信息
        TUserAmount amount = userAmountService.selectTUserAmountByUserId(user.getId());
        if (ObjectUtils.isEmpty(amount)) {
            throw new RuntimeException("账户不存在");
        }
        //查询以前的结算明细
        TUserAmountDetail detail = userAmountDetailService.findTUserAmountDetail(orderId,0,goodOrder.getOrderNo(),user.getId());
        //减去以前的明细
        if(!ObjectUtils.isEmpty(detail)){
            amount.setIncomeAmount(amount.getIncomeAmount() - detail.getSurplusAmount());
            amount.setStayPayAmount(amount.getStayPayAmount() + detail.getStayPayAmount());
            int i1 = userAmountService.updateTUserAmount(amount);
            if (i1 < 1) {
                throw new RuntimeException("更新账户失败");
            }
            //根据信息删掉重复数据,保留最新一条
            userAmountDetailService.deleteTUserAmountDetail(orderId,0,goodOrder.getOrderNo(),user.getId());
            //userAmountDetailService.deleteTUserAmountDetailById(detail.getId());
        }
        Integer stayPay = goodOrder.getPrice() * goodOrder.getBuyNum();
        Integer incomeAmount = 0;
        if(goodOrder.getUserStayPayPrice() < 1){
            if (goodOrder.getUserIdentity().equals(0)) {
                incomeAmount = goodOrder.getDefaultSettlementCountPrice();
                stayPay = stayPay - goodOrder.getDefaultSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(1)) {
                incomeAmount = goodOrder.getMemberSettlementCountPrice();
                stayPay = stayPay - goodOrder.getMemberSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(2)) {
                incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
                stayPay = stayPay - goodOrder.getTwoMemberSettlementCountPrice();
            }
        }else{
            stayPay = goodOrder.getUserStayPayPrice();
            if (goodOrder.getUserIdentity().equals(0)) {
                incomeAmount = goodOrder.getDefaultSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(1)) {
                incomeAmount = goodOrder.getMemberSettlementCountPrice();
            } else if (goodOrder.getUserIdentity().equals(2)) {
                incomeAmount = goodOrder.getTwoMemberSettlementCountPrice();
            }
        }
        amount.setIncomeAmount(amount.getIncomeAmount() + incomeAmount);
        amount.setStayPayAmount(amount.getStayPayAmount() - stayPay);
        int i1 = userAmountService.updateTUserAmount(amount);
        if (i1 < 1) {
            throw new RuntimeException("更新账户失败");
        }

        //插入资金详细
        TUserAmountDetail detail1 = new TUserAmountDetail();
        detail1.setUserId(user.getId());
        detail1.setDetailName(goodOrder.getGoodName());
        detail1.setDetailType(0);
        String text = "场次 " + DateUtils.parseDateToStr("MM/dd", goodOrder.getGoodDate()) + ",票面 " + goodOrder.getTicketPrice() + "," + goodOrder.getParagraph() + "段 ," + goodOrder.getGoodRow() + "行 ,座位号 " + goodOrder.getSeatNumber();
        detail1.setDetailRemark(text);
        detail1.setPrice(goodOrder.getPrice());
        detail1.setQuantity(goodOrder.getBuyNum());
        detail1.setStayPayAmount(stayPay);
        detail1.setSurplusAmount(incomeAmount);
        detail1.setOrderNo(goodOrder.getOrderNo());
        detail1.setOrderId(orderId);
        detail1.setGoodId(goodOrder.getGoodId());
        userAmountDetailService.insertTUserAmountDetail(detail1);

    }

}
